package fun.stgoder.easydarwin.jobs.bl;

import fun.stgoder.easydarwin.jobs.bl.model.Pusher1;
import fun.stgoder.easydarwin.jobs.bl.model.api.*;
import fun.stgoder.easydarwin.jobs.comm.Constants;
import fun.stgoder.easydarwin.jobs.comm.model.NV;
import fun.stgoder.easydarwin.jobs.comm.model.Param;
import fun.stgoder.easydarwin.jobs.comm.util.HttpUtil;
import fun.stgoder.easydarwin.jobs.comm.util.JsonUtil;
import fun.stgoder.easydarwin.jobs.comm.util.SqlUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class API {

    private static Logger logger = LoggerFactory.getLogger(API.class);

    private static Map<String, String> tokens = new HashMap<>();

    public static String login(String username, String password) throws Exception {
        String content = HttpUtil
                .get(Constants.EASYDARWIN_API_BASE + "/api/v1/login?username=" + username + "&password=" + password);

        Token token = JsonUtil.parse(content, Token.class);

        if (Constants.TEST_MODE)
            logger.info(token.getToken());

        tokens.put(username, token.getToken());

        return token.getToken();
    }

    public static void logout(String username) throws Exception {
        String token = tokens.get(username);
        if (StringUtils.isBlank(token))
            return;
        HttpUtil.get(Constants.EASYDARWIN_API_BASE + "/api/v1/logout", new NV[]{new NV("token", token)});
    }

    public static Pushers pushers(int start, int limit, String sort, String order, String q) throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/pushers?start=" + start + "&limit=" + limit;
        if (StringUtils.isNotBlank(sort))
            url += "&sort=" + sort;
        if (StringUtils.isNotBlank(order))
            url += "&order=" + order;
        if (StringUtils.isNotBlank(q))
            url += "&q=" + q;

        Pushers pushers;
        if (Constants.PRE_RECORD) {
            String content = HttpUtil.get(url);
            pushers = JsonUtil.parse(content, Pushers.class);
        } else {
            List<Pusher1> pusher1s = SqlUtil.select("select * from stream", Pusher1.class);
            List<Pusher> rows = new ArrayList<>();
            for (Pusher1 pusher1 : pusher1s) {
                Pusher pusher = new Pusher();
                pusher.setId(pusher1.getStreamId());
                pusher.setPath("/" + pusher1.getStreamId());
                pusher.setTransType("tcp");
                pusher.setStartAt("");
                rows.add(pusher);
            }
            pushers = new Pushers();
            pushers.setRows(rows);
            pushers.setTotal(rows.size());
        }

        return pushers;
    }

    public static Players players(int start, int limit, String sort, String order, String q) throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/players?start=" + start + "&limit=" + limit;
        if (StringUtils.isNotBlank(sort))
            url += "&sort=" + sort;
        if (StringUtils.isNotBlank(order))
            url += "&order=" + order;
        if (StringUtils.isNotBlank(q))
            url += "&q=" + q;

        String content = HttpUtil.get(url);

        Players players = JsonUtil.parse(content, Players.class);

        return players;
    }

    public static String start(String rtsp, String streamId, String transType, int idleTimeout, int heartbeatInterval)
            throws Exception {
        String id;
        if (Constants.PRE_RECORD) {
            String url = Constants.EASYDARWIN_API_BASE + "/api/v1/stream/start?url=" + rtsp + "&customPath=/" + streamId;
            if (StringUtils.isNotBlank(transType))
                url += "&transType=" + transType;
            if (idleTimeout > 0)
                url += "&idleTimeout=" + idleTimeout;
            if (heartbeatInterval > 0)
                url += "&heartbeatInterval=" + heartbeatInterval;

            String content = HttpUtil.get(url);

            id = JsonUtil.parse(content, String.class);
        } else {
            id = streamId;
            SqlUtil.insert("insert into `stream`(streamId, rtsp) values(:streamId, :rtsp)",
                    new Param().add("streamId", streamId).add("rtsp", rtsp));
        }
        return id;
    }

    public static String stop(String id) throws Exception {

        String content;
        if (Constants.PRE_RECORD) {
            String url = Constants.EASYDARWIN_API_BASE + "/api/v1/stream/stop?id=" + id;

            content = HttpUtil.get(url);
            content = JsonUtil.parse(content, String.class); // "OK" -> OK
        } else {
            SqlUtil.delete("delete from stream where streamId = :streamId", new Param("streamId", id));
            return id;
        }

        return content;
    }

    public static Folders folders(int start, int limit, String sort, String order, String q) throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/record/folders?start=" + start + "&limit=" + limit;
        if (StringUtils.isNotBlank(sort))
            url += "&sort=" + sort;
        if (StringUtils.isNotBlank(order))
            url += "&order=" + order;
        if (StringUtils.isNotBlank(q))
            url += "&q=" + q;

        String content = HttpUtil.get(url);

        Folders folders = JsonUtil.parse(content, Folders.class);

        return folders;
    }

    public static Files files(int folder, int start, int limit, String sort, String order, String q) throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/record/files?folder=" + folder + "&start=" + start
                + "&limit=" + limit;
        if (StringUtils.isNotBlank(sort))
            url += "&sort=" + sort;
        if (StringUtils.isNotBlank(order))
            url += "&order=" + order;
        if (StringUtils.isNotBlank(q))
            url += "&q=" + q;

        String content = HttpUtil.get(url);

        Files files = JsonUtil.parse(content, Files.class);

        return files;
    }

    public static UserInfo userInfo(String username) throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/userInfo";

        String token = tokens.get(username);
        String content = HttpUtil.get(url, new NV[]{new NV("token", token)});

        UserInfo userInfo = JsonUtil.parse(content, UserInfo.class);

        return userInfo;
    }

    public static String restart() throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/restart";

        String content = HttpUtil.get(url);
        content = JsonUtil.parse(content, String.class); // "OK" -> OK

        return content;
    }

    public static String getServerinfo() throws Exception {

        String url = Constants.EASYDARWIN_API_BASE + "/api/v1/getserverinfo";

        String serverinfo = HttpUtil.get(url);

        return serverinfo;
    }

    public static List<String> customPaths() throws Exception {
        Pushers pushers = pushers(0, 100, null, null, null);

        List<String> customPaths = new ArrayList<>();
        for (Pusher pusher : pushers.getRows()) {
            customPaths.add(pusher.getPath());
        }
        return customPaths;
    }

    public static List<String> streamIds() throws Exception {
        List<String> customPaths = customPaths();
        List<String> streamIds = new ArrayList<>();
        for (String customPath : customPaths) {
            streamIds.add(customPath.replace("/", ""));
        }
        return streamIds;
    }

    public static String pusherPath(String id) throws Exception {

        Pushers pushers = pushers(0, 2000, null, null, null);

        String path = null;
        for (Pusher pusher : pushers.getRows()) {
            if (StringUtils.equals(id, pusher.getId())) {
                path = pusher.getPath();
                break;
            }
        }

        return path;
    }

    public static String getPusherIdByStreamId(String streamId) throws Exception {
        Pushers pushers = pushers(0, 2000, null, null, null);
        String customPath = "/" + streamId;
        for (Pusher pusher : pushers.getRows()) {
            if (StringUtils.equals(customPath, pusher.getPath())) {
                return pusher.getId();
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {

        // login("admin", CodeUtil.md5("admin"));

        // logout("admin");

        // pushers(0, 100, null, null, null);

        // players(0, 100, null, null, null);

        // start("rtsp://admin:a00000000@192.168.1.84:554/h264/ch3/main/av_stream",
        // "/cam84", "TCP", 0, 0);

        // stop("bkHwk9OZRz");

        // folders(0, 100, null, null, null);

        // files(1, 0, 100, null, null, null);

        // restart();

    }
}
